package com.chushouya.order.rabbitmq.sender;

import com.chushouya.common.util.RabbitMQUtil;
import com.chushouya.order.constants.OrderTypeEnum;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.common.constant.RabbitMqQueueEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 快递预约消息发送器（延时发送）
 * 
 * @author chushouya
 */
@Component
@Slf4j
public class ExpressReservationMessageSender {

    @Resource
    private RabbitMQUtil rabbitMQUtil;

    /**
     * 发送快递预约消息（立即发送）
     * 
     * @param orderId 订单ID
     */
    public void sendExpressReservationMessage(Long orderId) {
        try {
            log.info("发送快递预约消息，订单ID: {}", orderId);
            rabbitMQUtil.sendMessage(RabbitMqQueueEnum.EXPRESS_RESERVATION.getQueueName(), orderId);
            log.info("快递预约消息发送成功，订单ID: {}", orderId);
        } catch (Exception e) {
            log.error("发送快递预约消息异常，订单ID: {}, 错误信息: {}", orderId, e.getMessage(), e);
            throw new RuntimeException("发送快递预约消息失败", e);
        }
    }

    /**
     * 发送快递预约消息（延时发送 - 秒）
     * 
     * @param orderId 订单ID
     * @param delaySeconds 延时秒数
     */
    public void sendExpressReservationMessage(Long orderId, Long delaySeconds) {
        try {
            log.info("发送快递预约延时消息，订单ID: {}, 延时: {}秒", orderId, delaySeconds);
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.EXPRESS_RESERVATION.getQueueName(), 
                orderId, 
                delaySeconds, 
                TimeUnit.SECONDS
            );
            log.info("快递预约延时消息发送成功，订单ID: {}, 延时: {}秒", orderId, delaySeconds);
        } catch (Exception e) {
            log.error("发送快递预约延时消息异常，订单ID: {}, 延时: {}秒, 错误信息: {}", orderId, delaySeconds, e.getMessage(), e);
            throw new RuntimeException("发送快递预约延时消息失败", e);
        }
    }

    /**
     * 发送快递预约消息（延时分钟）
     * 
     * @param orderId 订单ID
     * @param delayMinutes 延时分钟数
     */
    public void sendExpressReservationMessageDelayMinutes(Long orderId, int delayMinutes) {
        try {
            log.info("发送快递预约延时消息，订单ID: {}, 延时: {}分钟", orderId, delayMinutes);
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.EXPRESS_RESERVATION.getQueueName(), 
                orderId, 
                delayMinutes, 
                TimeUnit.MINUTES
            );
            log.info("快递预约延时消息发送成功，订单ID: {}, 延时: {}分钟", orderId, delayMinutes);
        } catch (Exception e) {
            log.error("发送快递预约延时消息异常，订单ID: {}, 延时: {}分钟, 错误信息: {}", orderId, delayMinutes, e.getMessage(), e);
            throw new RuntimeException("发送快递预约延时消息失败", e);
        }
    }

    /**
     * 发送快递预约消息（延时小时）
     * 
     * @param orderId 订单ID
     * @param delayHours 延时小时数
     */
    public void sendExpressReservationMessageDelayHours(Long orderId, int delayHours) {
        try {
            log.info("发送快递预约延时消息，订单ID: {}, 延时: {}小时", orderId, delayHours);
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.EXPRESS_RESERVATION.getQueueName(), 
                orderId, 
                delayHours, 
                TimeUnit.HOURS
            );
            log.info("快递预约延时消息发送成功，订单ID: {}, 延时: {}小时", orderId, delayHours);
        } catch (Exception e) {
            log.error("发送快递预约延时消息异常，订单ID: {}, 延时: {}小时, 错误信息: {}", orderId, delayHours, e.getMessage(), e);
            throw new RuntimeException("发送快递预约延时消息失败", e);
        }
    }

    /**
     * 发送带类型的快递预约消息（立即发送）
     * 
     * @param orderId 订单ID
     * @param messageType 消息类型
     */
    public void sendExpressReservationMessage(Long orderId, String messageType) {
        try {
            log.info("发送快递预约消息，订单ID: {}, 类型: {}", orderId, messageType);
            rabbitMQUtil.sendMessage(
                RabbitMqQueueEnum.EXPRESS_RESERVATION.getQueueName(), 
                messageType, 
                orderId
            );
            log.info("快递预约消息发送成功，订单ID: {}, 类型: {}", orderId, messageType);
        } catch (Exception e) {
            log.error("发送快递预约消息异常，订单ID: {}, 类型: {}, 错误信息: {}", orderId, messageType, e.getMessage(), e);
            throw new RuntimeException("发送快递预约消息失败", e);
        }
    }

    /**
     * 发送带类型的快递预约消息（延时发送）
     * 
     * @param orderId 订单ID
     * @param messageType 消息类型
     * @param delay 延时时间
     * @param timeUnit 时间单位
     */
    public void sendExpressReservationMessage(Long orderId, String messageType, long delay, TimeUnit timeUnit) {
        try {
            log.info("发送快递预约延时消息，订单ID: {}, 类型: {}, 延时: {}{}", 
                    orderId, messageType, delay, timeUnit.toString().toLowerCase());
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.EXPRESS_RESERVATION.getQueueName(), 
                messageType, 
                orderId, 
                delay, 
                timeUnit
            );
            log.info("快递预约延时消息发送成功，订单ID: {}, 类型: {}, 延时: {}{}", 
                    orderId, messageType, delay, timeUnit.toString().toLowerCase());
        } catch (Exception e) {
            log.error("发送快递预约延时消息异常，订单ID: {}, 类型: {}, 延时: {}{}, 错误信息: {}", 
                    orderId, messageType, delay, timeUnit.toString().toLowerCase(), e.getMessage(), e);
            throw new RuntimeException("发送快递预约延时消息失败", e);
        }
    }

    /**
     * 发送快递取消消息（立即发送）
     * 
     * @param orderEntity 订单ID
     */
    public void sendExpressCancelMessage(OrderEntity orderEntity) {
        final Long orderId = orderEntity.getOrderId();
        try {
            log.info("发送快递取消消息，订单ID: {}", orderEntity.getOrderNo());
            final Integer orderType = orderEntity.getOrderType();
            if (Objects.equals(orderType, OrderTypeEnum.DOOR_RECYCLE.value())){
                // 上门回收订单不取消快递
                log.info("上门回收订单不取消快递，订单ID: {}", orderEntity.getOrderNo());
                return;
            }
            rabbitMQUtil.sendMessage(
                RabbitMqQueueEnum.EXPRESS_CANCEL.getQueueName(), 
                "EXPRESS_CANCEL", 
                orderId
            );
            log.info("快递取消消息发送成功，订单ID: {}", orderId);
        } catch (Exception e) {
            log.error("发送快递取消消息异常，订单ID: {}, 错误信息: {}", orderId, e.getMessage(), e);
            throw new RuntimeException("发送快递取消消息失败", e);
        }
    }
}
